#include<iostream>
#include<unistd.h>
#include<string>
#include<vector>
#include<assert.h>
#include<cstdlib>
#include"test.hpp"
#include<ctime>
#include<sys/wait.h>
#include<sys/stat.h>

#define num 128
#define processnum 10

std::vector<task_t> tasks;

class channel
{   
 public:
    channel(int cmdfd,pid_t childpid,std::string&  processname)
    :_cmdfd(cmdfd)
    ,_childpid(childpid)
    ,_processname(processname)
    {
    }
 public:
    int _cmdfd;//发送的描述符
    pid_t _childpid;//子进程的pid
    std::string  _processname; //程序名字
};
void child_task()
{
     
    //read(0);
    while(true)
    {
        int cmdcode=0;
        int n=read(0,&cmdcode,sizeof(int));
        if(n==sizeof(int))
        {
            

            //执行cmdcodde任务
           // std::cout<<getpid()<<" child process receive a task ->  task_cmdcode : "<< cmdcode<<" "<< std::endl;
            if(cmdcode>=0 && cmdcode<tasks.size())
                    tasks[cmdcode]();
            sleep(1);
        }
        if(n==0)
        break;
    }
}
void Menu()
{
    std::cout << "####################################################" << std::endl;
    std::cout << "# 1. 刷新日志                 2. 刷新野区资源        #" << std::endl;
    std::cout << "# 3. 刷新英雄释放技能时间      4. 刷新英雄死亡时间     #" << std::endl;
    std::cout << "# 5.屏蔽敏感字,比如:cnm cs sb  0. 退出               #" << std::endl;
    std::cout << "#####################################################" << std::endl;
}
void init_pipe(std::vector<channel> *channels)
{
     std::vector<int> oldfds;
 for(int i=0;i<processnum;i++)
    {
        int pipefd[2];//临时空间
        int n=pipe(pipefd);
        assert(!n);
        (void)n;

        pid_t id=fork();
        
        if(id==0)//child process
        {
            //防止子进程继承了父进程的写端
            std::cout << "child: " << getpid() << " close history fd: ";
            for(auto fd : oldfds) {
                std::cout << fd << " ";
                close(fd);
            }
            std::cout << "\n";
            close(pipefd[1]);
            dup2(pipefd[0],0);
            child_task();


            exit(0);
        }

        //father process
        close(pipefd[0]);

        //初始化字段
        std::string name="process-"+ std::to_string(i);
        channels->push_back(channel(pipefd[1],id,name));
        oldfds.push_back(pipefd[1]);

    }
}
void debug(const std::vector<channel>& channels)
{
    for(const auto &c:channels)
    {
        std::cout<<c._cmdfd<<" "<<c._childpid <<" "<<c._processname<< std::endl;
    }
}
void ctrchild( const std::vector<channel>& channels)
{
    int which = 0;
    //int cnt=8;
    while(true)
    {
         int select = 0;
        Menu();
        std::cout << "Please Enter@ ";
        std::cin >> select;

        if(select <= 0 || select >= 6) break;
        //选择任务
        //int cmdcode=rand()%tasks.size();
        //选择哪一个进程进行工作
        //int processpos=rand()%channels.size();
        //发布任务
        int cmdcode = select - 1;

        std::cout<<"father publish a task -> task_cmdcode: "<<cmdcode<<std::endl;
        
        write(channels[which]._cmdfd,&cmdcode,sizeof(cmdcode));
        which++;
        which %= channels.size();
        // cnt--;
        // sleep(1);
    }
}
void Quitprocess(const std::vector<channel>& channels)
{
     for(const auto &c : channels)
    {
        close(c._cmdfd);
        waitpid(c._childpid, nullptr, 0);
    }
    // for(const auto &c:channels) close(c._cmdfd);
  
    //   for(const auto &c:channels) waitpid(c._childpid,nullptr,0);
     

}

int main()
{
    Load_tasks(&tasks);
    
    srand(time(nullptr)^getpid()^1023);//种一个随机种子
    std::vector<channel> channels;//定义一个结构体指针的数组

    //1.初始化
   init_pipe(&channels);

    //test

   // debug(channels);
    //2.控制子进程
    ctrchild(channels);


    //3.清理工作

    Quitprocess(channels);
    return 0;
 }